package com.agger.harmonyosthemeseditor.intelligent;

import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class FileManager
{

    public static boolean delete(String fileName)
    {
        File file = new File(fileName);
        if (!file.exists()) {return false;}
        else
        {
            if (file.isFile())
                return deleteFile(fileName);
            else
                return deleteDirectory(fileName);
        }
    }

    public static boolean deleteFile(String fileName)
    {
        File file = new File(fileName);
        if (file.exists() && file.isFile()) {return file.delete();}
        else {return false;}
    }

    public static boolean deleteDirectory(String dir)
    {
        String _dir = dir;
        if (!dir.endsWith(File.separator))
            _dir = dir + File.separator;
        File dirFile = new File(_dir);
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {return false;}
        boolean flag = true;
        File[] files = dirFile.listFiles();
        for (File file : files)
        {
            if (file.isFile())
            {
                flag = deleteFile(file.getAbsolutePath());
                if (!flag)
                    break;
            } else if (file.isDirectory())
            {
                flag = deleteDirectory(file.getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag) {return false;}
        return dirFile.delete();
    }

    public static boolean deleteDirectory(String dir,boolean includeSelf,boolean endWithError)
    {
        String _dir = dir;
        if (!dir.endsWith(File.separator))
            _dir = dir + File.separator;
        File dirFile = new File(_dir);
        if (endWithError || (!dirFile.exists()) || (!dirFile.isDirectory())) {return false;}
        boolean flag = true;
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++)
        {
            if (files[i].isFile())
            {
                flag = deleteFile(files[i].getAbsolutePath());
                if (endWithError || !flag)
                    break;
            }
            else if (files[i].isDirectory())
            {
                flag = deleteDirectory(files[i].getAbsolutePath(),true,endWithError);
                if (endWithError || !flag)
                    break;
            }
        }
        if (endWithError || !flag) {return false;}
        if(!includeSelf)return true;
        else return dirFile.delete();
    }

    public static int getFileRealSize(FileDescriptor fileDescriptor)
    {
        int size = -1;
        FileInputStream fis = null;
        try
        {
            fis = new FileInputStream(fileDescriptor);
            size = fis.available();
        }catch(Exception e){e.printStackTrace();}
        finally
        {
            if(fis!=null)
            {
                try{fis.close();}
                catch(Exception e){e.printStackTrace();}
            }
        }
        return size;
    }

    public static long getFileSize(FileDescriptor fileDescriptor)
    {
        long size = -1;
        FileChannel fc = null;
        FileInputStream fis = null;
        try
        {
            fis = new FileInputStream(fileDescriptor);
            fc = fis.getChannel();
            size = fc.size();
        }catch(Exception e){e.printStackTrace();}
        finally
        {
            if(fc!=null)
            {
                try{fc.close();}
                catch(Exception e){e.printStackTrace();}
            }
            if(fis!=null)
            {
                try{fis.close();}
                catch(Exception e){e.printStackTrace();}
            }
        }
        return size;
    }

    public static long getFileSize(File file)
    {
        long size = -1;
        FileChannel fc = null;
        FileInputStream fis = null;
        try
        {
            if(file.exists() && file.isFile())
            {
                fis = new FileInputStream(file);
                fc = fis.getChannel();
                size = fc.size();
            }
        }catch(Exception e){e.printStackTrace();}
        finally
        {
            if(fc!=null)
            {
                try{fc.close();}
                catch(Exception e){e.printStackTrace();}
            }
            if(fis!=null)
            {
                try{fis.close();}
                catch(Exception e){e.printStackTrace();}
            }
        }
        return size;
    }

    public static boolean copyDir(String sourcePath, String targetPath)
    {
        boolean result = true;
        try
        {
            File file = new File(sourcePath);
            String[] filePath = file.list();
            if (!(new File(targetPath)).exists())
            {
                (new File(targetPath)).mkdir();
            }
            for (String s : filePath)
            {
                if ((new File(sourcePath + File.separator + s)).isDirectory())
                    copyDir(sourcePath + File.separator + s, targetPath + File.separator + s);
                if (new File(sourcePath + File.separator + s).isFile())
                    result = result && copyFile(sourcePath + File.separator + s, targetPath + File.separator + s);
            }
        }catch (Exception e)
        {
            result = false;
        }
        return result;
    }

    public static boolean copyFile(String oldPath, String newPath)
    {
        return copyFile(new File(oldPath),new File(newPath));
    }

    public static boolean copyFile(File oldPath, File newPath)
    {
        return copyFile(oldPath.toPath(), newPath.toPath());
    }
    public static boolean copyFile(Path oldPath, Path newPath)
    {
        try
        {
            Files.copy(oldPath, newPath, StandardCopyOption.REPLACE_EXISTING);
            return true;
        }catch (Exception e){ e.printStackTrace(); return false;}
    }

    public static boolean copyFile(FileDescriptor oldPath, String newPath)
    {
        FileChannel inputChannel;
        FileChannel outputChannel;
        try
        {
            inputChannel = new FileInputStream(oldPath).getChannel();
            outputChannel = new FileOutputStream(newPath).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
            inputChannel.close();
            outputChannel.close();
            return true;
        }catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
    }

    public static FileDescriptor getFileFd(String Path)
    {
        try
        {
            return new FileInputStream(Path).getFD();
        }catch (Exception ex){return null;}
    }

    public static FileDescriptor getFileFd(File file)
    {
        try
        {
            return new FileOutputStream(file).getFD();
        }catch (Exception ex){return null;}
    }
}
